package com.derbysoft.ota.application.translator.rq;

import org.apache.commons.lang.StringUtils;

import com.derbysoft.modules.eip.translator.Translator;
import com.derbysoft.ota.application.translator.MetaDatas;
import com.derbysoft.ota.application.util.Strings;
import com.derbysoft.ota.interfaces.protocol._2009a.CountryNameType;
import com.derbysoft.ota.interfaces.protocol._2009a.PersonNameType;
import com.derbysoft.ota.interfaces.protocol._2009a.StateProvType;
import com.derbysoft.ota.interfaces.protocol._2009a.AddressType.StreetNmbr;
import com.derbysoft.ota.interfaces.protocol._2009a.CustomerType.Address;
import com.googlecode.functionalcollections.FunctionalIterables;
import com.googlecode.functionalcollections.Injector;

public class AddressRQTranslator implements Translator<Address, String> {

	@Override
	public String translate(Address source) {
		return new StringBuilder()
			.append(addresseeName(source)).append(MetaDatas.SPACE)
			.append(streetNumber(source)).append(MetaDatas.SPACE)
			.append(addressLine(source)).append(MetaDatas.COMMA)
			.append(cityName(source)).append(MetaDatas.SPACE)
			.append(stateProv(source)).append(MetaDatas.SPACE)
			.append(postCode(source)).append(MetaDatas.COMMA)
			.append(country(source))
			.toString();
	}

	private String addresseeName(Address source) {
		PersonNameType addresseeName = source.getAddresseeName();
		if (addresseeName == null) {
			return StringUtils.EMPTY;
		}
		return FunctionalIterables.make(addresseeName.getGivenName())
				.messagedIterator("Please provider us at least 1 given name").next()
				+ MetaDatas.SPACE + Strings.of(addresseeName.getSurname());
	}

	private String addressLine(Address source) {
		return FunctionalIterables.make(source.getAddressLine()).inject(
			new StringBuilder(), 
			new Injector<StringBuilder, String>() {
				public StringBuilder apply(StringBuilder memo, String input) {
					return memo.append(input).append(MetaDatas.SPACE);
				}
			}
		).toString();
	}

	private String country(Address source) {
		CountryNameType countryName = source.getCountryName();
		if (countryName == null) {
			return StringUtils.EMPTY;
		}
		return Strings.of(countryName.getValue()) + MetaDatas.SPACE + Strings.of(countryName.getCode());
	}

	private String postCode(Address source) {
		return Strings.of(source.getPostalCode());
	}

	private String stateProv(Address source) {
		StateProvType stateProv = source.getStateProv();
		if (stateProv == null) {
			return StringUtils.EMPTY;
		}
		return Strings.of(stateProv.getValue()) + MetaDatas.SPACE + Strings.of(stateProv.getStateCode());
	}

	private String cityName(Address source) {
		return Strings.of(source.getCityName());
	}

	private String streetNumber(Address source) {
		StreetNmbr streetNmbr = source.getStreetNmbr();
		if (streetNmbr == null) {
			return StringUtils.EMPTY;
		}
		return Strings.of(streetNmbr.getValue());
	}

}
